package com.lagou.study;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.threadpool.support.fixed.FixedThreadPool;
import org.apache.dubbo.rpc.RpcContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.*;

public class WatchingThreadPool extends FixedThreadPool implements Runnable {

    private  static  final Logger LOGGER = LoggerFactory.getLogger(WatchingThreadPool.class);

    private static final double TP90 = 0.90;
    private static final double TP99 = 0.99;
    private final Map<URL, ThreadPoolExecutor> THREAD_POOLS = new ConcurrentHashMap<URL, ThreadPoolExecutor>();

    public WatchingThreadPool(){
        Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(this,1,3, TimeUnit.SECONDS);
    }

    // 通过父类创建线程池
    @Override
    public Executor getExecutor(URL url) {
        final  Executor executor = super.getExecutor(url);
        if(executor instanceof  ThreadPoolExecutor){
            THREAD_POOLS.put(url,(ThreadPoolExecutor)executor);
        }
        return  executor;
    }

    public void run() {
        // 遍历线程池
        for (Map.Entry<URL,ThreadPoolExecutor> entry: THREAD_POOLS.entrySet()){
            final   URL  url = entry.getKey();
            final   ThreadPoolExecutor  executor = entry.getValue();
            // 计算相关指标
            final  int  activeCount  = executor.getActiveCount();
            final  int  poolSize = executor.getCorePoolSize();
            double  usedPercent = activeCount / (poolSize*1.0);
            LOGGER.info("线程池执行状态:[{}/{}:{}%]",activeCount,poolSize,usedPercent*100);
            if (usedPercent > TP90){
                if(RpcContext.getContext().getAttachment("methodA")!=null){
                    RpcContext.getContext().setAttachment("TP90#methodA",RpcContext.getContext().getAttachment("methodA"));
                }
                if(RpcContext.getContext().getAttachment("methodB")!=null){
                    RpcContext.getContext().setAttachment("TP90#methodB",RpcContext.getContext().getAttachment("methodB"));
                }
                if(RpcContext.getContext().getAttachment("methodC")!=null){
                    RpcContext.getContext().setAttachment("TP90#methodC",RpcContext.getContext().getAttachment("methodC"));
                }
                //LOGGER.error("超出警戒线TP90! host:{} 当前使用率是:{},URL:{}",url.getIp(),usedPercent*100,url);
            }
            if (usedPercent > TP99){
                if(RpcContext.getContext().getAttachment("methodA")!=null){
                    RpcContext.getContext().setAttachment("TP99#methodA",RpcContext.getContext().getAttachment("methodA"));
                }
                if(RpcContext.getContext().getAttachment("methodB")!=null){
                    RpcContext.getContext().setAttachment("TP99#methodB",RpcContext.getContext().getAttachment("methodB"));
                }
                if(RpcContext.getContext().getAttachment("methodC")!=null){
                    RpcContext.getContext().setAttachment("TP99#methodC",RpcContext.getContext().getAttachment("methodC"));
                }
                //LOGGER.error("超出警戒线TP99! host:{} 当前使用率是:{},URL:{}",url.getIp(),usedPercent*100,url);
            }
            if (usedPercent <= TP90) {
                RpcContext.getContext().clearAttachments();
            }
        }
    }
}
